package utils

import (
	"math"
	"strconv"
	"strings"
)

type Point struct {
	Latitude  float64
	Longitude float64
}

// 解析经纬度字符串为浮点数
func parseCoordinate(coord string) (float64, error) {
	value, err := strconv.ParseFloat(coord, 64)
	if err != nil {
		return 0.0, err
	}
	return value, nil
}

// 格式化浮点数为字符串（保留小数点后6位）
func formatCoordinate(coord float64) string {
	return strconv.FormatFloat(coord, 'f', 6, 64)
}

// 计算贝塞尔曲线上的点
func computeBezierCurve(points []Point) []Point {
	n := len(points) - 1 // 阶数
	var bezierPoints []Point

	for t := 0.0; t <= 1.0; t += 0.01 {
		var x, y float64
		for i := 0; i <= n; i++ {
			b := bernsteinPolynomial(i, n, t)
			x += b * points[i].Longitude
			y += b * points[i].Latitude
		}
		bezierPoints = append(bezierPoints, Point{Latitude: y, Longitude: x})
	}

	return bezierPoints
}

// 计算伯恩斯坦多项式
func bernsteinPolynomial(i, n int, t float64) float64 {
	binomial := float64(factorial(n) / (factorial(i) * factorial(n-i)))
	return binomial * math.Pow(t, float64(i)) * math.Pow(1-t, float64(n-i))
}

// 计算阶乘
func factorial(n int) int {
	if n <= 1 {
		return 1
	}
	return n * factorial(n-1)
}

func Cnm(input []string) []string {
	points := make([]Point, len(input))
	for i, str := range input {
		coords := strings.Split(str, ",")
		lat, _ := parseCoordinate(coords[0])
		lng, _ := parseCoordinate(coords[1])
		points[i] = Point{Latitude: lat, Longitude: lng}
	}
	bezierPoints := computeBezierCurve(points)
	output := make([]string, len(bezierPoints))
	for i, p := range bezierPoints {
		latStr := formatCoordinate(p.Latitude)
		lngStr := formatCoordinate(p.Longitude)
		output[i] = latStr + "," + lngStr
	}
	return output
}
